//下载参数
var http = require("http");
var https = require("https");
var fs = require("fs");
var path = require("path");
let urlFun = require('url');

var dlInfo = {
    files : [],
    pathmap : {},
    savePath : "C:/Users/flyswatter/Desktop/test/dltest",
    domain : "http://www.aaabbbccc.com",
    prePath : "http://www.aaabbbccc.com",
};



/**
 * 删除文件夹下所有问价及将文件夹下所有文件清空
 * @param {*} path 
 */
 function emptyDir(path) {
    const files = fs.readdirSync(path);
    files.forEach(file => {
        const filePath = `${path}/${file}`;
        const stats = fs.statSync(filePath);
        if (stats.isDirectory()) {
            emptyDir(filePath);
        } else {
            fs.unlinkSync(filePath);
        }
    });
}
 
/**
 * 删除指定路径下的所有空文件夹
 * @param {*} path 
 */
function rmEmptyDir(path, level=0) {
    const files = fs.readdirSync(path);
    if (files.length > 0) {
        let tempFile = 0;
        files.forEach(file => {
            tempFile++;
            rmEmptyDir(`${path}/${file}`, 1);
        });
        if (tempFile === files.length && level !== 0) {
            fs.rmdirSync(path);
        }
    }
    else {
        level !==0 && fs.rmdirSync(path);
    }
}
 
/**
 * 清空指定路径下的所有文件及文件夹
 * @param {*} path 
 */
function clearDir(path) {
    emptyDir(path);
    rmEmptyDir(path);
}
 
function mkdirs(dirpath, callback) {
    if(fs.existsSync(dirpath)){
        callback(dirpath);
    }else{
        //尝试创建父目录，然后再创建当前目录
        mkdirs(path.dirname(dirpath), function(){
            fs.mkdir(dirpath, callback);
        });
    }
};
/**
 * 下载回调
 */
function getHttpReqCallback (fileinfo,timeoutEvent) {
    fileinfo.progress = 0;
    var callback = function(res) {
        fileinfo.statusCode = res.statusCode;
        if(fileinfo.statusCode!=200){
            console.log("request: " + fileinfo.url +" referer: "+fileinfo.referer + " httpstatus: " + res.statusCode);
            return;
        }
        var contentLength = parseInt(res.headers['content-length']);
        
        var downLength = 0;
    
        var out = fs.createWriteStream(fileinfo.savepath);
        res.on('data', function (chunk) {
            
            downLength += chunk.length;
            var progress =  Math.floor(downLength*100 / contentLength);
            var str = "dl progress ->"+ progress +"%";
            fileinfo.progress = progress;
            // console.log(str);
            //写文件
            out.write(chunk, function () {
                //console.log(chunk.length);
                if(progress==100){
                    if(["frame","css"].includes(fileinfo.filetype)){
                        dealFileLink(fileinfo)
                    }
                }
            });
            
        });
        res.on('end', function() {
            // console.log("end downloading " + fileinfo.url);
            out.end()
            
            fileinfo.isEnd = true;
            clearTimeout(timeoutEvent)
            if (isNaN(contentLength)) {
                console.log(fileinfo.url + " content length error");
                return;
            }
            if (downLength < contentLength) {
                console.log(fileinfo.url + " download error, try again");
                return;
            }
            
        });
    };

    return callback;
}

/**
 * 下载开始
 */
function startDownloadTask (fileinfo,isCreated) {
    if (!fs.existsSync(fileinfo.dirName)) {
        if(isCreated) return;
        mkdirs(fileinfo.dirName,()=>{
            startDownloadTask(fileinfo,true)
        })
        return;
    }
    // console.log("start downloading " + fileinfo.url);
    var req = null;
    var tmpurl = fileinfo.url;
    if(tmpurl.indexOf("?")==-1){
        tmpurl+="?"+Math.random()
    }else{
        tmpurl+="&"+Math.random()
    }
    var timeoutEvent = setTimeout(function() {
        // req.abort();
    }, 2000);
    if(fileinfo.url.indexOf("https")==0){
        req = https.request(tmpurl, getHttpReqCallback(fileinfo,timeoutEvent));
    }else{
        req = http.request(tmpurl, getHttpReqCallback(fileinfo,timeoutEvent));
    }

    req.on('error', function(e){
        console.log("request " + tmpurl + " error, try again");
    });
    req.end();
}



// startDownloadTask('http://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-8/v8.5.41/bin/apache-tomcat-8.5.41.tar.gz','D://1024Workspace//extension','apache-tomcat-8.5.41.tar.gz');

//startDownloadTask('下载地址','本地存储路径','文件名');



function dealFileLink(fileitem){
    
    var urlInfo  = urlFun.parse(fileitem.url)
    fs.readFile(fileitem.savepath,"utf8",(err,data)=>{
        if(err){
            console.error(err)
        }else{
            var content = data;
            content = content.replace(/src=['"](.*?)['"]|url[('"]+(.*?)['")]+|href=['"](.*?)['"]/g, function(matchstr,link,link1,link2) {
                link = link || link1 || link2;
                // console.log(matchstr +"  " + link);
                if(!link){
                    console.log(matchstr +"  " + link);
                    // console.log(arguments)
                    return matchstr;
                }
                if(link.indexOf("?")!=-1){
                    link = link.substring(0,link.indexOf("?"))
                }
                const tmplink = link.toLowerCase();
                if(tmplink.startsWith("mailto") || tmplink.startsWith("tel:") 
                    || tmplink.startsWith("#") || tmplink.startsWith("javascript")
                    || tmplink.startsWith("data:")) return matchstr;
                if(!link.startsWith("http")){
                    if(link.startsWith("/")){
                        var tmppath = urlInfo.path;
                        if(tmppath.indexOf(".")!=-1){  //带文件名的路径去掉一级
                            tmppath = path.dirname(urlInfo.path);
                        }
                        var preUrl = [];
                        tmppath.split("/").map(item=>{  //计算相对路径
                            if(item) preUrl.push("..")
                        })
                        if(preUrl.length>0){
                            preUrl = preUrl.join("/")
                        }else{
                            preUrl = "."
                        }
                        matchstr = matchstr.replace(link,preUrl+link)
                        link = urlInfo.protocol+"//"+urlInfo.hostname+link;
                    }else{
                        var relpath = path.join(path.dirname(urlInfo.path),link);
                        relpath = relpath.replace(/\\/g,"/")
                        link = urlInfo.protocol+"//"+urlInfo.hostname+relpath;
                    }
                }else{
                    if(link.indexOf(dlInfo.domain)==-1) return matchstr;
                }
                var curfinfo = getFileInfo(link,dlInfo.prePath,fileitem.url)
                
                startDownLoadByHttpUrl(curfinfo);
                return matchstr;
            });
            fs.writeFile(fileitem.savepath, content, 'utf8', (err)=>{
            });
        }
    })
}

function startDownLoadByHttpUrl(fileinfo){
    if(dlInfo.pathmap[fileinfo.url]) return;
    dlInfo.files.push(fileinfo)
    dlInfo.pathmap[fileinfo.url] = true;
    startDownloadTask(fileinfo)
}

function getFileInfo(url,basepath,referer){
    
    if(url.indexOf("#")!=-1){
        url = url.substring(0,url.indexOf("#"))
    }
    if(url.indexOf("?")!=-1){
        url = url.substring(0,url.indexOf("?"))
    }
    var filename = path.basename(url)
    var filepath = path.dirname(url)
    var extname = path.extname(url);
    var filetype = "";
    var subpath = "";
    extname = extname.replace(".","")
    extname = extname.toLowerCase();

    if(!extname){
        filename = "index.html";
        filepath = url;
        // url+="/index.html"
        extname = "html";
    }
    if(["html","htm"].includes(extname)){
        filetype = "frame"
    }else if(["js"].includes(extname)){
        filetype = "js"
    }else if(["css"].includes(extname)){
        filetype = "css"
    }else if(["png","jpg","jpeg","bmp","svg","gif"].includes(extname)){
        filetype = "image"
    }else{
        filetype = "other"
    }
    if(filetype=="frame"){
        var a1=1;
    }
    if(!basepath){
        subpath = "";
    }else{
        if(filepath.indexOf(basepath)!=-1){
            subpath = filepath.replace(basepath,"")
        }else{
            subpath = filetype
        }
    }
    
    var domain = "http://www.aaabbbccc.com";
    if(url.indexOf("://")!=-1){
        try{
            var tmp  = url.substring(0,url.indexOf("/",8))
            domain = tmp || domain;
        }catch(ex){

        }
    }
    var dirName = dlInfo.savePath+"/"+subpath;
    dirName = dirName.replace(/[\/]{2,10}/g,"/");
    return {
        url: url,
        filename: filename,
        filepath: filepath,
        extname: extname,
        filetype : filetype,
        subpath : subpath,
        domain : domain,
        dirName : dirName,
        savepath : dirName+"/"+filename,
        referer : referer||"",
    }
}
module.exports = {
    initDlInfo(savePath,url=""){
        var savePath = savePath || "C:/Users/flyswatter/Desktop/test";
        dlInfo.savePath = savePath;
        const fileinfo = getFileInfo(url);
        dlInfo = {
            files : [],
            pathmap : {},
            savePath : savePath,
            domain : "www.aaabbbccc.com",
            prePath : fileinfo.filepath
        }
        if (!fs.existsSync(dlInfo.savePath)) {
            fs.mkdirSync(dlInfo.savePath);
        }
        fs.writeFile(dlInfo.savePath+"/desc.txt", "下载来源: "+url, 'utf8',()=>{});
        startDownLoadByHttpUrl(fileinfo);
    },
    getDlInfo(){
        return dlInfo;
    },
    startHttpDl: startDownLoadByHttpUrl,
    dealFilesPath(){
        // dealFilesPath();
    },
    clearDir(path){  //比较危险,先不用
        clearDir(path)
    }
}